package com.google.code.swingonfire.border;

import java.awt.Color;
import java.awt.Image;
import java.awt.image.BufferedImage;

public class ShadowCircleCacheEntry
{

    private final Image image;

    public ShadowCircleCacheEntry(ShadowCircleCacheKey key)
    {
        super();

        image = createImage(key);
    }

    public Image getImage()
    {
        return image;
    }

    private static Image createImage(ShadowCircleCacheKey key)
    {
        int innerRadius = key.getRadius() - key.getSize();
        int outerRadius = key.getRadius() + key.getSize();

        if (outerRadius <= 0)
        {
            return null;
        }

        BufferedImage image = new BufferedImage(outerRadius * 2, outerRadius * 2, BufferedImage.TYPE_INT_ARGB);
        Color outerColor = key.getOuterColor();
        Color innerColor = key.getInnerColor();
        int da = outerColor.getAlpha() - innerColor.getAlpha();
        int dr = outerColor.getRed() - innerColor.getRed();
        int dg = outerColor.getGreen() - innerColor.getGreen();
        int db = outerColor.getBlue() - innerColor.getBlue();

        for (int y = 0; y < outerRadius; y += 1)
        {
            for (int x = 0; x < outerRadius; x += 1)
            {
                double d = Math.sqrt((x * x) + (y * y));

                if (d < innerRadius)
                {
                    d = 1;
                }
                else if (d > outerRadius)
                {
                    d = 0;
                }
                else
                {
                    d = 1 - ((d - innerRadius) / (outerRadius - innerRadius));
                }

                d = 1 - (d * d);

                int color =
                    ((int) Math.round(innerColor.getAlpha() + (da * d)) << 24)
                        | ((int) Math.round(innerColor.getRed() + (dr * d)) << 16)
                        | ((int) Math.round(innerColor.getGreen() + (dg * d)) << 8)
                        | ((int) Math.round(innerColor.getBlue() + (db * d)));

                image.setRGB(outerRadius - x, outerRadius - y, color);
                image.setRGB(outerRadius + x, outerRadius - y, color);
                image.setRGB(outerRadius - x, outerRadius + y, color);
                image.setRGB(outerRadius + x, outerRadius + y, color);
            }
        }

        return image;
    }
}
